<?php
defined('BASEPATH') OR exit('No direct script access allowed');

/**
 * 订单
 * @author www.dingwei.cn
 */
class Order extends MY_Controller {
	
	/**
	 * @var DlnOrderModel
	 */
	public $mOrder = null;
	
	/**
	 * @var AdmSettingModel
	 */
	public $mStt = null;
	
	/**
	 * @var DlnUserModel
	 */
	public $mUser = null;

    /**
     * @var DlnMessageModel
     */
    public $mMessage = null;
	public function __construct(){
		parent::__construct();
		$this->loadModel('DlnOrderModel', 'mOrder');
		$this->loadModel('DlnMessageModel', 'mMessage');
	    if($this->userStatus != 2 && ! strpos($this->ruri, 'order/log')){
			$this->appReturn(0, '请实名认证');
		}
	}
	
	/**
	 * 获取列表
	 */
	public function getList(){
        $this->loadModel('ConsumerOrderModel', 'mConOrder', 'consumer');
		$this->loadModel('AdmSettingModel', 'mStt', 'admin');
		//表单验证
		$vConf = array(
				array('latitude', '纬度', 'required|numeric'),
				array('longitude', '经度', 'required|numeric'),
				array('status', '状态', 'required|in_list[1,2,3]'),
				array('page', '页码', 'required|numeric'),
				array('order', '排序', 'required|in_list[0,1,2,3]'),
		);
		$this->formDataValidation($vConf);
		
		$status = post('status');
		$order = post('order');
		$rang = $this->mStt->get('deliveryman_range,deliveryman_region_status,rob_expect_time', 'deliveryman');
		$latitude = post('latitude');
		$longitude = post('longitude');
		$select = '(ACOS(SIN(('.$latitude.' * 3.1415) / 180 )
						*SIN((o.latitude * 3.1415) / 180 ) + COS(('
						.$latitude.' * 3.1415) / 180 ) * COS((o.latitude * 3.1415) / 180 ) * COS(('
						.$longitude.' * 3.1415) / 180 - (o.longitude * 3.1415) / 180 ) ) * 6380 ) as distance';
		
		$this->db->select('o.id,o.type,o.code,o.number,o.send_user,o.longitude,o.latitude,
                    o.send_mobile,o.send_address,o.send_to_longitude,o.send_to_latitude,o.send_to_user,
					o.send_to_mobile,o.send_to_address,o.distance as send_distance,o.income,o.status,o.addtime,
				  o.rob_expect_time,co.expect_arrive_time as consumer_expect_time,o.expect_arrive_time'.($status <= 2 ? ','.$select : ''));
		
		if($status == 1){
			$this->db->where('distance <=', $rang['deliveryman_range'])
					 ->where('o.rob_expect_time >', time());
			if($order){
				if($order == 1){
					$this->db->order_by('distance desc');
				}elseif($order == 2){
					$this->db->order_by('o.distance desc');
				}elseif($order == 3){
					$this->db->order_by('o.expect_income desc');
				}
			}else{
				$this->db->order_by('o.id desc');
			}
		}elseif($status > 1){
			$this->db->join($this->mOrder->tbRelationOrder.' ro', 'ro.order_id = o.id')
					 ->where('ro.deliveryman_id', $this->userId)
					 ->order_by('ro.addtime desc');
		}
		
		if($rang['deliveryman_region_status'] > 0){
			$this->db->where('o.county_id', $this->userCountyId);
		}
		
		$this->db->join($this->mConOrder->tbOrder.' co', 'co.id = o.order_id')
                ->where_in('o.type', $this->userOrderType)
		         ->where('o.status', $status);
	
		$data = $this->mOrder->appPage($this->mOrder->tbOrder.' o', post('page'), true);

		foreach ($data['list'] as $k => $v){
			$data['list'][$k]['send_time'] = $this->mOrder->showBeautifulTimeForMat($v['expect_arrive_time'],
			    ($v['status'] == 1 ? $v['addtime'] : time()));
			$data['list'][$k]['compute_time'] = $v['expect_arrive_time'];
			if($status <= 2){
				$v['distance'] = $v['distance'] * 1000;
                $data['list'][$k]['distance'] = $v['distance'] > 1000
                    ? round($v['distance'] / 1000, 2).'km' : ceil($v['distance']).'m';
			}else{
				$data['list'][$k]['distance'] = 0;
			}
			$data['list'][$k]['type_str'] = $this->mOrder->type($v['type']);
			$data['list'][$k]['status_str'] = $this->mOrder->status($v['status']);
			$data['list'][$k]['send_distance'] = $v['send_distance'] > 1000 
			? round($v['send_distance'] / 1000, 2).'km' : ceil($v['send_distance']).'m';
            $data['list'][$k]['expect_arrive_time'] = date('Y-m-d H:i', $v['consumer_expect_time']);
		}
		
		$this->appReturn(1, '', $data);
	}
	
	/**
	 * 抢单
	 */
	public function add(){
	
		$this->loadModel('AdmSettingModel', 'mStt', 'admin');
		//表单验证
		$vConf = array(
				array('id', '运单id', 'required|numeric'),
		);
		$this->formDataValidation($vConf);
		
		$id = post('id');
		$tI = $this->mStt->get('deliveryman_region_status', 'deliveryman');
		$this->db->select('status,rob_expect_time,expect_arrive_time,addtime')
				 ->where('id', $id)
				 ->where_in('type', $this->userOrderType);
		
		if($tI > 0){
		    $this->db->where('county_id', $this->userCountyId);
		}
		
		$data = $this->mOrder->getOne($this->mOrder->tbOrder);
		
		
		if( ! $data){
			$this->appReturn(0, '运单不存在');
		}
		if($data['status'] == 5){
			$this->appReturn(0, '运单已取消');
		}
		
		if($data['status'] > 1){
			$this->appReturn(0, '运单已被别人抢走');
		}
		
		if(time() > $data['rob_expect_time']){
			$this->appReturn(0, '已超时');
		}
		
		$this->db->trans_begin();
		$dbData = [
				 'deliveryman_id' => $this->userId,
				 'order_id' => $id,
				 'addtime' => time()
		];
		
		if( ! $this->mOrder->insert($this->mOrder->tbRelationOrder, $dbData)){
			$this->db->trans_rollback();
			$this->appReturn(0, '抢单失败');
		}
		
		$time = $data['expect_arrive_time'] - $data['addtime'] + time();
		$this->db->where('id', $id);
		if( ! $this->mOrder->update($this->mOrder->tbOrder, ['status' => 2, 
				'order_month' => date('Ymd'),'expect_arrive_time' => $time])){
			$this->db->trans_rollback();
			$this->appReturn(0, '抢单失败');
		}
		
		$this->db->select('order_total,jpush_code')->where('id', $this->userId);
		$tA = $this->mUser->getOne($this->mUser->tbUser);
		$total = (int)$tA['order_total'] + 1;
		$this->db->where('id', $this->userId);
		if( ! $this->mUser->update($this->mUser->tbUser, ['order_total' => $total])){
			$this->db->trans_rollback();
			$this->appReturn(0, '抢单失败');
		}
		
		//添加日志记录
		if( ! $this->mOrder->addLog($id, '配送员'.$this->userName.'【'.$this->userMobile.'】准备取货')){
		    $this->db->trans_rollback();
		    $this->appReturn(0, '抢单失败');
		}

		//添加消息
        $msgData = array(
            'order_id' => $id,
            'type' => 2,
            'deliveryman_id' => $this->userId,
            'content' => '请及时到店取货',
            'addtime' => time(),
        );
        if(!($this->mMessage->save($msgData))){
            $this->db->trans_rollback();
            $this->appReturn(0, '抢单失败');
        }
        deliverymanJpush('接单提醒', '请及时到店取货', 1, array($tA['jpush_code']));

		$this->db->trans_commit();
		$this->appReturn(1, '抢单成功');
	}
	
	/**
	 * 确认取货
	 */
	public function pickup(){
		
		//表单验证
		$vConf = array(
				array('id', '订单id', 'required|numeric'),
		);
		$this->formDataValidation($vConf);
		$id = post('id');
		$this->db->select('o.status')
				 ->join($this->mOrder->tbRelationOrder.' ro', 'ro.order_id = o.id')
				 ->where('o.id', $id)
				 ->where('ro.deliveryman_id', $this->userId);
		$data = $this->mOrder->getOne($this->mOrder->tbOrder.' o');
		if( ! $data){
			$this->appReturn(0, '运单不存在');
		}
		
		if($data['status'] > 2){
			$this->appReturn(0, '已取货');
		}
		
		if($data['status'] == 5){
			$this->appReturn(0, '运单已取消');
		}
		
		if($data['status'] != 2){
			$this->appReturn(0, '运单不能取货');
		}
		
		$data = [
				 'pickup_time' => time(),
				 'status' => 3
		];
		
		$this->db->trans_begin();
		
		$this->db->where('id', $id);
		if( ! $this->mOrder->update($this->mOrder->tbOrder, $data)){
		    $this->db->trans_rollback();
			$this->appReturn(0, '取货失败');
		}
		
		//添加日志记录
		if( ! $this->mOrder->addLog($id, '配送员'.$this->userName.'【'.$this->userMobile.'】正在配送中')){
		    $this->db->trans_rollback();
		    $this->appReturn(0, '取货失败');
		}

        //添加消息
        $msgData = array(
            'order_id' => $id,
            'type' => 2,
            'deliveryman_id' => $this->userId,
            'content' => '配送员已取货',
            'addtime' => time(),
        );
		//消息是否已删除
        if(!$this->mMessage->messageIsExist($id)){
            //消息未删除，更新消息
            $query = $this->mMessage->save($msgData, 0, $id);
        }else{
            $query = $this->mMessage->save($msgData);
        }

        if(!$query){
            $this->db->trans_rollback();
            $this->appReturn(0, '取货失败');
        }
        $this->db->select('order_total,jpush_code')->where('id', $this->userId);
        $tA = $this->mUser->getOne($this->mUser->tbUser);
        deliverymanJpush('取货提醒', '请及时送达', 1, array($tA['jpush_code']));

		$this->db->trans_commit();
		$this->appReturn(1, '已取货');
	}
	
	/**
	 * 确认已完成
	 */
	public function complete(){

		//表单验证
		$vConf = array(
				array('id', '订单id', 'required|numeric'),
		);
		$this->formDataValidation($vConf);
		$id = post('id');
		$this->db->select('o.status,o.income,o.expect_arrive_time,o.order_id,o.store_id')
				 ->join($this->mOrder->tbRelationOrder.' ro', 'ro.order_id = o.id')
				 ->where('o.id', $id)
				 ->where('ro.deliveryman_id', $this->userId);
		$data = $this->mOrder->getOne($this->mOrder->tbOrder.' o');
		if( ! $data){
			$this->appReturn(0, '运单不存在');
		}
		
		if($data['status'] == 5){
			$this->appReturn(0, '运单已取消');
		}
		
		if($data['status'] != 3){
			$this->appReturn(0, '运单不能标记为完成');
		}
		
		$this->db->trans_begin();
		
		//改变订单状态
		$dbData = [
				 'complete_time' => time(),
				 'order_month' => date('Ymd'),
				 'status' => 4
		];
		$this->db->where('id', $id);
		if( ! $this->mOrder->update($this->mOrder->tbOrder, $dbData)){
			$this->db->trans_rollback();
			$this->appReturn(0, '保存失败');
		}
		
		//保存余额变化日志
		$dbData = [
					'deliveryman_id' => $this->userId,
					'order_id' => $id,
					'amount' => $data['income'],
					'type' => 1,
					'status' => 2,
					'addtime' => time()
		];
		if( ! $this->mUser->insert($this->mUser->tbAmountDetails, $dbData)){
			$this->db->trans_rollback();
			$this->appReturn(0, '保存失败');
		}
		
		//保存余额
		$amount = $this->mUser->getAmount($this->userId) + $data['income'];
		$this->db->select('order_complete_total,order_overtime_total,jpush_code')
				 ->where('id', $this->userId);
		$tA = $this->mUser->getOne($this->mUser->tbUser);
		$total = (int)$tA['order_complete_total'] + 1;
		$dbData = ['order_complete_total' => $total, 'amount' => $amount];
		if($data['expect_arrive_time'] < time()){
			$dbData['order_overtime_total'] = (int)$tA['order_overtime_total'] + 1;
		}
		$this->db->where('id', $this->userId);
		if( ! $this->mUser->update($this->mUser->tbUser, $dbData)){
			$this->db->trans_rollback();
			$this->appReturn(0, '保存失败');
		}
		
		//添加日志记录
		if( ! $this->mOrder->addLog($id, '你的订单已送达，请确认已收到。')){
		    $this->db->trans_rollback();
		    $this->appReturn(0, '保存失败');
		}
        $this->loadModel('ConsumerOrderModel', 'mConOrder', 'consumer');
		//原订单信息
        $this->db->select('id,status')
            ->where('id', $data['order_id']);
        $orderInfo = $this->mConOrder->getOne($this->mConOrder->tbOrder);
		if($orderInfo['status'] == 3){
            //更改原始订单状态
            if(!($this->mConOrder->save(array('status' => 4,'confirmtime' => time()), 0, $data['order_id']))){
                $this->db->trans_rollback();
                $this->appReturn(0, '保存失败');
            }
            //增加商家余额
            // 打款给商家
            $this->loadModel('MerchantUserModel', 'mMerchant', 'merchant');
            $this->loadModel('MerchantBalanceModel', 'mBalance', 'merchant');
            $orderInfo = $this->mConOrder->appGetInfo($data['order_id']);
            $merInfo = $this->mMerchant->getInfo($data['store_id'], 0, true);

            $bal = $this->mMerchant->save(array('balance' => $merInfo['balance']+$orderInfo['merchant_income']), $data['store_id']);
            if(!$bal){
                $this->db->trans_rollback();
                $this->appReturn(0, '商家余额保存失败');
            }
            //添加余额记录
            $balanceLog = array(
                'merchant_id' => $data['store_id'],
                'type' => 5,
                'pay_type' => 1,
                'amount' => $orderInfo['merchant_income'],
                'percent' => $orderInfo['percent'],
                'param' => $data['order_id'],
                'status' => 2,
                'addtime' => time(),
                'confirm_time' => time(),
            );
            $bLog = $this->mBalance->save($balanceLog);
            if (!$bLog){
                $this->db->trans_rollback();
                $this->appReturn(0, '商家余额保存失败');
            }

            $rS = $this->mConOrder->saveOrderLog($data['order_id'], '待评价', '已送达', 'deliveryman', $this->userId);
            if (!$rS){
                $this->db->trans_rollback();
                $this->appReturn(0, '订单日志保存失败');
            }
            //增加销量
            $productList = $this->mConOrder->getOrderProductList($data['order_id']);

            $this->loadModel('ConsumerProductModel', 'mProduct', 'consumer');
            foreach ($productList as $v){
                if ($v['variant_id'] > 0){
                    $query = $this->mProduct->savePropertyVariant(array('sale_quantity'=>$v['v_sale_quantity'] + $v['quantity']),$v['product_id'],$v['variant_id']);
                    if(!$query){
                        $this->db->trans_rollback();
                        $this->appReturn(0,'销量增加失败');
                    }
                }
                $qy = $this->mProduct->save(array('sale_quantity'=>$v['sale_quantity']+ $v['quantity']), $v['product_id']);
                if(!$qy){
                    $this->db->trans_rollback();
                    $this->appReturn(0,'销量增加失败');
                }
            }
        }
        //添加消息
        $msgData = array(
            'order_id' => $id,
            'type' => 2,
            'deliveryman_id' => $this->userId,
            'content' => '配送员已送达',
            'addtime' => time(),
        );
        //消息是否已删除
        if(!$this->mMessage->messageIsExist($id)){
            //消息未删除，更新消息
            $query = $this->mMessage->save($msgData, 0, $id);
        }else{
            $query = $this->mMessage->save($msgData);
        }

        if(!$query){
            $this->db->trans_rollback();
            $this->appReturn(0, '取货失败');
        }

        deliverymanJpush('送达提醒', '订单已送达', 1, array($tA['jpush_code']));

        //用户推送消息
        $msgData = array(
            'title' => '订单已送达',
            'content' => '订单已送达,请当面验收检查',
            'addtime' => time(),
        );
        $this->loadModel('ConsumerMessageModel', 'mConMessage', 'consumer');
        //删除消息查看记录
        $info = $this->mConOrder->getInfo($data['order_id'], 0, 0, true);
        $this->mConMessage->deleteView($info['consumer_id'], 0, $data['order_id']);
        if(!($this->mConMessage->save($msgData, 0, $data['order_id']))){
            $this->db->trans_rollback();
            $this->appReturn(0, '消息保存失败');
        }
        jpush($msgData['title'], $msgData['content'], 1, array($info['jpush_code']), 3, $data['order_id'], $info['expense_type']);

        //商家推送消息
        $this->loadModel('merchantMessageModel', 'mMerMsg', 'merchant');
        //删除消息查看记录
        $this->mMerMsg->deleteView($info['merchant_id'], 0, $data['order_id']);
        if(!($this->mMerMsg->save($msgData, 0, $data['order_id']))){
            $this->db->trans_rollback();
            $this->appReturn(0, '消息保存失败');
        }
        MerchantJpush($msgData['title'], $msgData['content'], 1, array($info['merchant_jpush_code']), 3, $data['order_id']);

		$this->db->trans_commit();
		$this->appReturn(1, '已保存');
	}
	
	/**
	 * 异常报备
	 */
	public function abnormal(){
			
		//表单验证
		$vConf = array(
				array('id', '订单id', 'required|numeric'),
				array('type', '类型', 'required'),
				array('content', '内容', 'required'),
		);
		$this->formDataValidation($vConf);
		$type = post('type');
		$id = post('id');
		$this->db->select('o.status,o.income')
				 ->join($this->mOrder->tbRelationOrder.' ro', 'ro.order_id = o.id')
				 ->where('o.id', $id)
				 ->where('ro.deliveryman_id', $this->userId);
		$data = $this->mOrder->getOne($this->mOrder->tbOrder.' o');
		if( ! $data){
			$this->appReturn(0, '运单不存在');
		}
		
		if($data['status'] == 4 || $data['status'] == 5){
			$this->appReturn(0, '不能报备');
		}
		$tS = $this->mOrder->apConfig($type);
		if( ! $tS || ! is_string($tS)){
			$this->appReturn(0, '参数错误');
		}
		
		$this->db->where('order_id', $id);
		if($this->mOrder->count($this->mOrder->tbOrderAp)){
			$this->appReturn(0, '已提交异常报备，不能重复提交');
		}
		
		$data = [
				'deliveryman_id' => $this->userId,
				'order_id' => $id,
				'content' => trim(post('content')),
				'type' => $type,
				'addtime' => time()
		];
		
		if($this->mOrder->insert($this->mOrder->tbOrderAp, $data)){
			$this->appReturn(1, '保存成功');
		}
		
		$this->appReturn(0, '保存失败');
	}
	
	/**
	 * 获取今日记录信息
	 */
	public function getTodayData(){
		
		$end = date('Ymd');
		$start = date('Ymd', strtotime('-30day'));
		$this->db->select('o.order_month,count(o.id) as count')
				 ->join($this->mOrder->tbRelationOrder.' ro', 'ro.order_id = o.id')
				 ->where('o.order_month >', $start)
				 ->where('o.order_month <=', $end)
				 ->where('ro.deliveryman_id', $this->userId)
				 ->order_by('o.order_month asc')
                 ->group_by('o.order_month');
		$dateGroup = $this->mOrder->getAll($this->mOrder->tbOrder.' o');
		$this->db->select('portrait,name,score')
				 ->where('id', $this->userId);
		$user = $this->mUser->getOne($this->mUser->tbUser);
		$user['portrait'] = $user['portrait'] ? base_url($user['portrait']) : getDefaultImg();
		$user['score'] = $user['score'] ? $user['score'] : 0;

		$date = [];
		foreach ($dateGroup as $k => $v){
		    if($v['count'] > 0){
    			$date[] = [
    						'date' =>['y' => substr($v['order_month'], 0, 4), 
    								 'm' => substr($v['order_month'], 4, 2), 
    								 'd' => substr($v['order_month'], 6, 2)],
    						'quantity' => $v['count']
    			];	
		    }
		}
		
		$data = [
					'user' => $user,
					'date' => $date
			];
		
		$this->appReturn(1, '', $data);
	}
	
	/**
	 * 完成列表
	 */
	public function completeList(){
		
		//表单验证
		$vConf = array(
				array('date', '日期', 'required'),
				array('page', '页码', 'required|integer'),
		);
		$this->formDataValidation($vConf);
		$date = strtotime(post('date'));
		$end = strtotime('+1day', $date);
		if( ! $date){
			$this->appReturn(0, '日期格式错误');
		}
		
		$this->db->select('o.id,o.code,o.send_user,o.income')
				 ->join($this->mOrder->tbRelationOrder.' ro', 'ro.order_id = o.id')
				 ->where('ro.deliveryman_id', $this->userId)
				 ->where('o.status', 4)
				 ->where('o.complete_time >=', $date)
				 ->where('o.complete_time <', $end)
				 ->order_by('o.complete_time desc');
		
		$data = $this->mOrder->appPage($this->mOrder->tbOrder.' o', post('page'));
		$this->appReturn(1, '', $data);
	}
	
	/**
	 * 异常报备列表
	 */
	public function apList(){
		
		//表单验证
		$vConf = array(
				array('date', '日期', 'required'),
				array('page', '页码', 'required|integer'),
		);
		$this->formDataValidation($vConf);
		
		$date = post('date');
		if( ! strtotime(post('date'))){
			$this->appReturn(0, '日期格式错误');
		}
		
		$this->db->select('o.id,o.code,o.send_user,o.income')
				 ->join($this->mOrder->tbOrderAp.' ro', 'ro.order_id = o.id')
				 ->where('ro.deliveryman_id', $this->userId)
				 ->where('o.status >', 1)
				 ->where('o.order_month', str_replace('-', '', $date))
				 ->order_by('ro.addtime desc');
		
		$data = $this->mOrder->appPage($this->mOrder->tbOrder.' o', post('page'));
		$this->appReturn(1, '', $data);
	}
	
	/**
	 * 获取异常报备配置
	 */
	public function apConfig(){
	    
	    $tA = $this->mOrder->apConfig();
	    $data = [];
	    foreach ($tA as $k => $v){
	        $data[] = ['id' => $k, 'label' => $v];
	    }
	    
	    $this->appReturn(1, '', $data);
	}
	
	/**
	 * 获取运单详情
	 */
	public function getInfo(){
        $this->loadModel('AdmSettingModel', 'mSetting', 'admin');

		$info = $this->mOrder->getInfo(post('id'), $this->userId);
		if( ! $info){
			$this->appReturn(0, '运单不存在');
		}

		$info['compute_time'] = strtotime($info['expect_arrive_time']);

        $info['expect_arrive_time'] = date('Y-m-d H:i', $info['consumer_expect_time']);

		$this->appReturn(1, '', $info);
	}
	
	/**
	 * 获取订单的类型配置
	 */
	public function type(){
	 
	    $tA = $this->mOrder->type();
	    $data = [];
	    foreach ($tA as $k => $v){
	        $data[] = ['type' => $k, 'name' => $v];
	    }
	    $this->appReturn(1, '', $data);
	}
	
	/**
	 * 获取订单日志记录
	 */
	public function log(){
	    
	    $this->loadModel('AdmSettingModel', 'mSett', 'admin');
	    
	    //表单验证
	    $vConf = array(
	               array('id', '订单id', 'required|integer'),
	            );
	    $this->formDataValidation($vConf, ['id' => get('id')]);
	    
	    $id = get('id');
	    if($id < 1){
	       show_404();          
	    }
	   
	    $this->db->select('o.id,o.longitude,o.latitude,o.send_to_longitude,
                o.send_to_latitude,o.status,u.longitude as u_longitude,u.latitude as u_latitude')
	             ->join($this->mOrder->tbRelationOrder.' ro', 'ro.order_id = o.id', 'left')
	             ->join($this->mUser->tbUser.' u', 'u.id = ro.deliveryman_id', 'left')
	             ->where('o.order_id', $id);
	    
	    $info = $this->mOrder->getOne($this->mOrder->tbOrder.' o');
	    if((bool)$info){
	        $this->db->select('description,addtime')
	                 ->where('order_id', $info['id'])
	                 ->order_by('addtime desc');
	        $tA = $this->mOrder->getAll($this->mOrder->tbOrderLog);
	        $info['log'] = $tA;
	    }
	    $this->view('order/log', ['data' => $info, 'ak' => $this->mSett->get('map_key')]);    
	}
}